﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace Sinacor.Infra.UI.Controls.SmartClient.DataGrid
{
    public class DataGridColumnCollection : KeyedCollection<string, Microsoft.Windows.Controls.DataGridColumn>
    {
        /// <summary>
        /// Construtor que inicializa DataGrid
        /// </summary>
        /// <param name="dataGrid">DataGrid para o qual a coleção pertence</param>
        internal DataGridColumnCollection(SinacorDataGrid dataGrid)
            : base()
        {
            _dataGrid = dataGrid;
            this.DataGrid.InternalColumns.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(InternalColumns_CollectionChanged);
        }

        void InternalColumns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            // Sincroniza a coleção interna de colunas com a coleção externa, só utilizada 
            // no auto generate columns
            switch (e.Action)
            {
                case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                    if (!this.Contains((Microsoft.Windows.Controls.DataGridColumn)e.NewItems[0]))
                        base.InsertItem(e.NewStartingIndex, (Microsoft.Windows.Controls.DataGridColumn)e.NewItems[0]);

                    break;

                case System.Collections.Specialized.NotifyCollectionChangedAction.Move:
                    break;

                case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
                    if (this.Contains((Microsoft.Windows.Controls.DataGridColumn)e.OldItems[0]))
                        base.RemoveItem(e.OldStartingIndex);

                    break;
                case System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
                    if (this[e.NewStartingIndex] != ((Microsoft.Windows.Controls.DataGridColumn)e.NewItems[0]))
                        base.SetItem(e.NewStartingIndex, (Microsoft.Windows.Controls.DataGridColumn)e.NewItems[0]);

                    break;
                case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
                    if (this.Count > 0)
                        base.ClearItems();
                    
                    break;
                default:
                    break;
            }
        }

        private SinacorDataGrid _dataGrid;
        /// <summary>
        /// DataGrid para o qual a coleção pertence
        /// </summary>
        internal SinacorDataGrid DataGrid
        {
            get { return _dataGrid; }
        }

        protected override void InsertItem(int index, Microsoft.Windows.Controls.DataGridColumn item)
        {
            this.ValidateColumnName(item);

            base.InsertItem(index, item);
            this.DataGrid.InternalColumns.Insert(index, item);
        }

        protected override void SetItem(int index, Microsoft.Windows.Controls.DataGridColumn item)
        {
            this.ValidateColumnName(item);

            base.SetItem(index, item);
            this.DataGrid.InternalColumns[index] = item;
        }

        protected override void RemoveItem(int index)
        {
            base.RemoveItem(index);
            this.DataGrid.InternalColumns.RemoveAt(index);
        }

        protected override void ClearItems()
        {
            base.ClearItems();
            this.DataGrid.InternalColumns.Clear();
        }

        protected override string GetKeyForItem(Microsoft.Windows.Controls.DataGridColumn item)
        {
            if (item is IDataGridColumn)
                return ((IDataGridColumn)item).Name;
            else
                // Utilizado no auto generate columns
                return Guid.NewGuid().ToString();
        }

        private void ValidateColumnName(Microsoft.Windows.Controls.DataGridColumn item)
        {
            if (item == null)
                throw new ArgumentNullException("item");

            if (!(item is IDataGridColumn))
                throw new InvalidOperationException("The column must implement IDataGridColumn");

            if (string.IsNullOrEmpty(((IDataGridColumn)item).Name))
                throw new InvalidOperationException("The column's name cannot be empty. Please don't use the property 'x:Name', use 'Name'");

            foreach (Microsoft.Windows.Controls.DataGridColumn column in this)
            {
                if (((IDataGridColumn)column).Name == ((IDataGridColumn)item).Name)
                    throw new InvalidOperationException(string.Format("The column's name '{0}' already exists", ((IDataGridColumn)item).Name));
            }
        }
    }
}
